﻿
//	------------------------------------------------------------------------------
//                                       _                          
//              _ __ ___   ___ _ __ ___ | |__  _ __ __ _ _ __   ___ 
//             | '_ ` _ \ / _ \ '_ ` _ \| '_ \| '__/ _` | '_ \ / _ \
//             | | | | | |  __/ | | | | | |_) | | | (_| | | | |  __/
//             |_| |_| |_|\___|_| |_| |_|_.__/|_|  \__,_|_| |_|\___|
//                                                     
//	------------------------------------------------------------------------------

#region - License -
//
//	------------------------------------------------------------------------------                                                   
//	         Copyright (c) 2010 Peter Vyvey (peter.vyvey@chiliware.be)
//	------------------------------------------------------------------------------
//
//
//	This file is part of CHILIWARE MEMBRANE.
//
//	CHILIWARE MEMBRANE is free software: you can redistribute it and/or modify
//	it under the terms of the GNU Lesser General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	CHILIWARE MEMBRANE is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU Lesser General Public License for more details.
//
//	You should have received a copy of the GNU Lesser General Public License
//	along with CHILIWARE MEMBRANE.  If not, see <http://www.gnu.org/licenses/>.
//
//
#endregion

#region - Changes -

//	peter.vyvey@chiliware.be     2010-08-09      Created.

#endregion

#region - Using -

using System;
using System.Text;
using System.Security.Cryptography;

#endregion

namespace Chiliware.Membrane.Extension
{
    #region - StringExtension -

	/// <summary>
	/// Extends functionality on strings.
	/// </summary>
    public static class StringExtension
    {
        #region - Public static methods -

		/// <summary>
		/// Formats a string with the given array of objects.
		/// </summary>
		/// <param name="value">The string value.</param>
		/// <param name="parameters">The array of formatting parameters.</param>
		/// <returns>The formatted string.</returns>
        public static string FormatWith(this string value, params object[] parameters)
        {
            return string.Format(value, parameters);
        }

		/// <summary>
		/// Returns the string value or a given default value if NULL or empty. 
		/// </summary>
		/// <param name="value">The string value.</param>
		/// <param name="defaultValue">The default value.</param>
		/// <returns>The string value or the the default value if NULL or empty.</returns>
        public static string IfEmpty(this string value, string defaultValue)
        {
            if (!value.IsNotEmpty())
            {
                return defaultValue;
            }
            return value;
        }

		/// <summary>
		/// Checks if the given string is empty.
		/// </summary>
		/// <param name="value">The string value.</param>
		/// <returns>TRUE if the string is empty, FALSE otherwise.</returns>
        public static bool IsEmpty(this string value)
        {
            if (value != null)
            {
                return (value.Length == 0);
            }
            return true;
        }

		/// <summary>
		/// Checks if the given string is not empty.
		/// </summary>
		/// <param name="value">The string value.</param>
		/// <returns>TRUE if the string is not empty, FALSE otherwise.</returns>
        public static bool IsNotEmpty(this string value)
        {
            return !value.IsEmpty();
        }

		/// <summary>
		/// Truncates a string at the given length.
		/// </summary>
		/// <param name="value">The string value.</param>
		/// <param name="maxLength">The maximum length of the string.</param>
		/// <returns>The truncated string.</returns>
        public static string TruncateAt(this string value, int maxLength)
        {
            if ((value != null) && (value.Length > maxLength))
            {
                return value.Substring(0, maxLength);
            }
            return value;
        }

		/// <summary>
		/// Truncates a string at the given length, thereafter the suffix is added.
		/// </summary>
		/// <param name="value">The string value.</param>
		/// <param name="maxLength">The maximum length of the string.</param>
		/// <param name="suffix">The suffix to add to the string.</param>
		/// <returns>The truncated string with suffix.</returns>
        public static string TruncateAt(this string value, int maxLength, string suffix)
        {
            if ((value != null) && (value.Length > maxLength))
            {
                return (value.Substring(0, maxLength) + suffix);
            }
            return value;
        }

        /// <summary>
        /// Converts a camelcased string to a user friendly text by replacing the uppercase characters by a combination of a space and lowercase character
        /// </summary>
        /// <param argumentName="camelCaseString">Camel case formatted string</param>
        /// <returns></returns>
        public static string Humanize(this string value)
        {
			StringBuilder humanText = new StringBuilder();

			if (!string.IsNullOrWhiteSpace(value))
			{
				for (int i = 0; i < value.Length; i++)
				{
					if (value.Substring(i, 1) == value.Substring(i, 1).ToUpper())
					{
						if (i != 0)
						{
							humanText.Append(" ");
							humanText.Append(value.Substring(i, 1).ToLower());
						}
						else
						{
							humanText.Append(value.Substring(i, 1));
						}
					}
					else
					{
						humanText.Append(value.Substring(i, 1).ToLower());
					}
				}

				humanText = humanText.Replace("_", string.Empty);
				humanText = humanText.Replace("  ", " ");
			}

			return humanText.ToString().Trim();
        }


        /// <summary>
        /// Calculates a hash for the specified string value.
        /// </summary>
        /// <param name="value">The string value.</param>
        /// <returns>The hash value.</returns>
        public static string Hash(this string value)
        {
            value.CatchNullArgument("value");

#if (!SILVERLIGHT)

			using (MD5CryptoServiceProvider cryptoProvider = new MD5CryptoServiceProvider())
            {
                byte[] dataBytes = Encoding.Default.GetBytes(value);
                byte[] encryptedBytes = cryptoProvider.ComputeHash(dataBytes);
                StringBuilder hashCode = new StringBuilder();
                Array.ForEach(encryptedBytes, b => hashCode.Append(b.ToString("x2").ToUpperInvariant()));

                return hashCode.ToString();
			}

#endif

#if (SILVERLIGHT)

			string hashCode = MD5Core.GetHashString(value);
			return hashCode;

#endif
		}

        #endregion
    }

    #endregion
}
